import {useState} from "react";
import {Button, Image, message, Upload} from "antd";
import {UploadOutlined} from "@ant-design/icons";

// 这个组件，会把Upload选择的文件，通过子传父方式向父组件传递数据
/*
* 其它组件调用本组件的方法：
* （1）在父组件中调用本组件时，组件有一个属性，叫做 onGetFile=====> <UploadFileCom   onGetFile={getFile} />
* (2) 本组件会自动去掉重复转载的文件，以文件名及文件大小作为判定依据
* （3）按钮的名称，可以自定义，这里暂定为 “ 发送数据 ”
* （4）父组件使用本组件时，需要在父组件中执行如下步骤：
  第二部：创建一个函数，名字叫getFile，这个函数会被传递到本组件中，记住关键代码：
  const getFile=async (files)=>{
        const formData=new FormData();
        *
        {这里填充其它代码，如：formData.append('eqName','测试8-挖掘机');}
        *
        *
        files.forEach((item)=>{
            formData.append('eqPhotoList',item) //'eqPhotoList'要根据后端接口具体定
        })
        const res= await saveOneEquipmentAPI(formData) //执行axios 方法
       message.success(res.msg)
    }
    第三步：在return()中放置本组件
     <UploadFileCom   onGetFile={getFile} />  //onGetFile={getFile}在这里写死，如果需要
     * 增加其他属性，可以添加
  *

* */


// 记住，这个组件要接收一个参数，并解构，这里d的onGetFile是一个函数
export default function UploadFileCom({onGetFile}) {

    const [fileList,setFileList]=useState([])
    const [previewOpen, setPreviewOpen] = useState(false);
    const [previewImage, setPreviewImage] = useState('');


    // 定义一个状态参数，用于向其他组件传递数据
    const [sendFile,setSendFile]=useState([])

    // 执行时间在beforeUpload函数之后，newFileList是在beforeUpload过滤后确定新的全部文件数组
    // 这个方法必须要要有
    // 通过onChange方法，自动向sendFile状态参数中存进需要向其他组件发送的数据
    const onChange=({fileList:newFileList})=>{
        setFileList(newFileList)
        const fileList=newFileList.map((item) => {
            // 这里直接把File类型文件导出
            return item.originFileObj;
        })
        setSendFile(fileList)
    }

    // 配合预览图片代码
    const getBase64 = (file) =>
        new Promise((resolve, reject) => {
            const reader = new FileReader();
            reader.readAsDataURL(file);
            reader.onload = () => resolve(reader.result);
            reader.onerror = (error) => reject(error);
        });
    // 预览图片固定代码
    const onPreview=async (file)=>{
        if (!file.url && !file.preview) {
            file.preview = await getBase64(file.originFileObj);
        }
        setPreviewImage(file.url || file.preview);
        setPreviewOpen(true);
    }


    // 这个用于限制文件大小，过滤重复文件
    // 函数的参数file，是针对本次上传的文件（文件数组中每一个元素）
    const beforeUpload=(file)=>{
        // fileSize的值是file的文件大小，单位是MB
        const fileSize=file.size/1024/1024;
        // 如果
        if (fileSize>20){
            message.error('文件必须小于20M')
            // 如果文件大于20MB,返回一个Upload.LIST_IGNORE,表示不把这个file文件放进数组里面，不显示出来
            return Upload.LIST_IGNORE;
        }

        // 拷贝一份状态参数，注意，这个fileList是不包含这次上传的文件的
        const newFileList=[...fileList];

        // 创建一个字符串参数，空字符串或者是 Upload.LIST_IGNORE
        let uploadState=''

        // 判断选中的每个文件是否与原来文件相同，通过文件名称，大小作为判定依据
        newFileList.forEach(item=>{
            // 通过文件的名称，大小作为判定依据文件是否一样
            if (item.originFileObj.name===file.name && item.originFileObj.size===file.size){
                // 如果文件与原数组中一个元素一样，返回一个Upload.LIST_IGNORE,表示不把这个file文件放进数组里面，不显示出来
                uploadState= Upload.LIST_IGNORE;
            }
        })

        // 返回Upload.LIST_IGNORE，使得停止上传该文件（不是整个文件数组）
        // 这里的意义，就是如果选择文件过程中，防止Upload会默认发起post请求，杜绝的办法是return一个false,或者Upload.List_IGNORE
        if (uploadState.length>0){
            return uploadState;
        }
        else {
            return  false
        }
    }


    // 删除文件
    const onRemove=(file)=>{
        // 查找到需要删除的文件的索引号
        const index=   fileList.indexOf(file)
        // 复制一个跟初始fileList一样的数组
        const newFileList=  [...fileList];
        // newFileList删除指定索引号的元素，记住，splice函数是直接在原数组删除，但又能返回一个被删除掉的元素组成的数组
        newFileList.splice(index-1,1)
        // 存进原来的状态参数中
        setFileList(newFileList);
    }


    return (
        <div>
            Upload组件
            <hr/>

            {/*  Upload说明
            listType:上传列表的内建样式，支持四种基本样式 text, picture, picture-card 和 picture-circle
            fileList:上传文件列表，这个参数必须有，要用useState状态参数转载，用于存储需要上传的文件列表
            onChange:上传文件列表跟变更后的操作，执行时间在beforeUpload之后，必须要有这个函数，用于把变更后的文件列表存储到useState中
            onPreview：图片预览组件，可选，后面有配套的函数
            maxCount：限制上传数量最大值
            onRemove：必选参数，用于删除不需要的文件
            multiple:布尔值，用于确定是否单选文件还是多选文件

            */}
            <Upload
                listType='picture-card'
                fileList={fileList}
                onChange={onChange}
                onPreview={onPreview}
                multiple={true}
                beforeUpload={beforeUpload}
                maxCount={15}
                onRemove={onRemove}
            >

                {fileList.length<15 && <Button  type="primary" icon={<UploadOutlined />}>
                    Upload
                </Button>}

            </Upload>

            {/*放大缩小图片固定代码*/}
            {previewImage && (
                <Image
                    wrapperStyle={{
                        display: 'none',
                    }}
                    preview={{
                        visible: previewOpen,
                        onVisibleChange: (visible) => setPreviewOpen(visible),
                        afterOpenChange: (visible) => !visible && setPreviewImage(''),
                    }}
                    src={previewImage}
                />
            )}
            <br/>
            {/*按钮的名称，可以自定义，这里暂定为 “ 发送数据  ” */}
            <Button type='primary' onClick={()=>onGetFile(sendFile)}>发送数据</Button>
        </div>
    )
}

